#include <render/output/window.h>
#include <app/Application.h>
#include <app/modules/Ainput.h>

#include <GLFW/glfw3.h>
#include <GLES3/gl3.h>

Ainput *input;

void keyCallback ( GLFWwindow*, int, int, int, int );
void cursorKeyCallback ( GLFWwindow*, int, int, int );
void cursorPositionCallback ( GLFWwindow*, double, double );
void resizeCallback ( GLFWwindow*, int, int );

Window::Window ( Application *appPtr ) {
    
    app = appPtr;
    
    glfwInit ();
    if ( app -> settings.MSAA > 0 ) {
        glfwWindowHint( GLFW_SAMPLES, app -> settings.MSAA );
    }
    if ( !app -> settings.windowResizeble ) {
        glfwWindowHint ( GLFW_RESIZABLE, false );
    }
    window = glfwCreateWindow ( app -> settings.windowWidth, app -> settings.windowHeight, 
                                app -> settings.windowName.c_str(), nullptr, nullptr);
    
    glfwMakeContextCurrent ( window );
    
    glfwSetKeyCallback ( window, keyCallback );
    glfwSetMouseButtonCallback ( window, cursorKeyCallback );
    glfwSetCursorPosCallback ( window, cursorPositionCallback );
    glfwSetWindowSizeCallback ( window, resizeCallback );
    
    input = &( app -> input );
}

bool Window::isClosed () {
    return glfwWindowShouldClose ( window );
}

void Window::Clear ( float R, float G, float B, float A ) {
    glClearColor ( R, G, B, A );
}

void Window::Update () {
    glfwSwapBuffers ( window );
}

Window::~Window () {
    glfwDestroyWindow ( window );
    glfwTerminate ();
}



void keyCallback ( GLFWwindow* window, int key, int scancode, int action, int mods ) {
    input -> keyboard.key = key;
    
    if ( action == GLFW_PRESS ) {
        input -> keyboard.action = PRESSED;
    } else if ( action == GLFW_REPEAT ) {
        input -> keyboard.action = CLICKED;
    } else if ( action == GLFW_RELEASE ) {
        input -> keyboard.action = UNPRESSED;
    }
}

void cursorKeyCallback ( GLFWwindow* window, int button, int action, int mods ) {
    if ( button == GLFW_MOUSE_BUTTON_LEFT ) {
        input -> mouse.key = MOUSE_LEFT_BUTTON;
    } else if ( button == GLFW_MOUSE_BUTTON_MIDDLE ) {
        input -> mouse.key = MOUSE_MIDDLE_BUTTON;
    } else if ( button == GLFW_MOUSE_BUTTON_RIGHT ) {
        input -> mouse.key = MOUSE_RIGHT_BUTTON;
    }
    
    
    if ( action == GLFW_PRESS ) {
        input -> mouse.action = PRESSED;
    } else if ( action == GLFW_REPEAT ) {
        input -> mouse.action = CLICKED;
    } else if ( action == GLFW_RELEASE ) {
        input -> mouse.action = UNPRESSED;
    }
}


void cursorPositionCallback ( GLFWwindow* window, double xpos, double ypos ) {
    input -> mouse.posX = xpos;
    input -> mouse.posY = ypos;
}

void resizeCallback ( GLFWwindow* window, int width, int height ) {
    glViewport ( 0, 0, width, height );
}
